package gr.upatras.uniexamtimetable;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/* 
 * 
 */
/**
 * Correlation Estimation is the estimation of common students between two exams.
 * 
 * @author spirosag
 */
public class CorrelationEstimation {
	
	private String examCode1;		//examCode of 1st exam
	private String examCode2;		//examCode of 2nd exam
	
	
	/**
	 * <code>correlation == 0</code> if there are no common students,
	 * <code>correlation == 100</code> if all students are common.
	 */
	private int correlation;

	/**
	 * Constructs a CorrelationEstimation object with the given values.
	 * 
	 * @param examCode1 code of the first exam
	 * @param examCode2 code of the second exam
	 * @param correlation correlation estimation
	 */
	public CorrelationEstimation(String examCode1, String examCode2,
			int correlation) {
		this.examCode1 = examCode1;
		this.examCode2 = examCode2;
		this.correlation = correlation;
	}		
	
	/**
	 * Constructs a CorrelationEstimation objects with the default values.
	 */
	public CorrelationEstimation() {
		this.examCode1 = "sample code 1";
		this.examCode2 = "sample code 2";
		this.correlation = 0;		
	}

	
	
	/* Prints the status of the Object in multiple lines */
	void printStatus() {
		System.out.println("Correlation Estimation:");
		System.out.println("1st Exam Code: " + examCode1
				+ ", 2nd Exam Code: " + examCode2 
				+ ", Correlation: " + correlation);
		System.out.println();
	}

	/**
	 * @return the code of the 1st exam
	 */
	public String getExamCode1() {
		return examCode1;
	}

	/**
	 * @param examCode1 the examCode1 to set.
	 */
	public void setExamCode1(String examCode1) {
		this.examCode1 = examCode1;
	}

	/**
	 * @return the code of the second exam
	 */
	public String getExamCode2() {
		return examCode2;
	}

	/**
	 * @param examCode2 the examCode2 to set
	 */
	public void setExamCode2(String examCode2) {
		this.examCode2 = examCode2;
	}

	/**
	 * @return the correlation
	 */
	public int getCorrelation() {
		return correlation;
	}

	/**
	 * @param correlation the correlation to set. Correlation range is [0,100].
	 * 					  <code>correlation == 0</code> if there are no common students,
	 * 					  <code>correlation == 100</code> if all students are common.
	 */
	public void setCorrelation(int correlation) {
		this.correlation = correlation;
	}

	/**
	 * Returns the values of this object's variables in a single 
	 * string with explanatory labels. Overrides the java.lang.ObjecttoString()
	 * 
	 * @return a string with the values of this objects variables 
	 */
	public String toString() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(String.format("1st exam code: %s, ", examCode1));
		stringBuilder.append(String.format("2nd exam code: %s, ", examCode2));
		stringBuilder.append(String.format("Correlation estimation: %s", correlation));
		return stringBuilder.toString();
	}
	
	/**
	 * Exports a list of CorrelationEstimation objects to a json file.
	 * 
	 * @param corList a list of CorrelationEstimation objects
	 * @param filename the filename of the json file to export to
	 */
	public static void exportToJson(
			List<CorrelationEstimation> corList, String filename) {
		
		BufferedWriter writer = null;
		Gson gson = new Gson();
		

		System.out.printf("Trying to export to %s ...%n", filename);
		
		try {
			writer = new BufferedWriter(new FileWriter(filename));
			
			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<CorrelationEstimation>>(){}.getType();
			gson.toJson(corList, collectionType, writer);
		} catch (IOException e) {
			System.err.printf("Sorry, couldn't export to %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				writer.close();
			} catch (IOException e){
				System.err.println("Sorry, couldn't properly close the buffered writer");
				e.printStackTrace();
			}
		}
		System.out.printf("Success: %d obcjects were exported.%n", corList.size());
	}
	
	/**
	 * Imports a list of <code>CorrelationEstimation</code> objects from a json file.
	 *  
	 * @param filename the name of the json file to export from
	 * @return a <code>List</code> of <code>CorrelationEstimation</code> objects 
	 */
	public static List<CorrelationEstimation> importFromJson(String filename) {
		
		BufferedReader reader = null;
		Gson gson = new Gson();
		List<CorrelationEstimation> corList = null;
		
		System.out.printf("Trying to import from %s ...%n", filename);

		try {
			reader = new BufferedReader(new FileReader(filename));
			
			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<CorrelationEstimation>>(){}.getType();
			corList = gson.fromJson(reader, collectionType);
		} catch (IOException e) {
			System.out.printf("Sorry, couldn't import from %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				System.err.println("Sorry, couldn't close the buffered reader.");
				e.printStackTrace();
			}
		}
		System.out.printf("Success: %d obcjects were imported.%n", corList.size());
		return corList;		
	}	
	

}
